package top.ezzz.rpc.server;

import cn.hutool.core.util.RandomUtil;
import io.grpc.solon.annotation.GrpcService;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import top.ezzz.rpc.protobuf.AddressBookServiceGrpc;
import top.ezzz.rpc.protobuf.PersonProto;

import java.util.ArrayList;

@Slf4j
@GrpcService
public class AddressBookService extends AddressBookServiceGrpc.AddressBookServiceImplBase {

    @Override
    public void getAddressBook(PersonProto.GetAddressBookRequest request, StreamObserver<PersonProto.AddressBook> responseObserver) {
        PersonProto.Person person = PersonProto.Person.newBuilder()
                .setId(1)
                .setName(request.getOwner())
                .build();
        responseObserver.onNext(PersonProto.AddressBook.newBuilder().addPeople(person).build());
        responseObserver.onCompleted();
    }

    @Override
    public StreamObserver<PersonProto.Person> addPeople(StreamObserver<PersonProto.AddPeopleResponse> responseObserver) {
        ArrayList<String> result = new ArrayList<>();
        return new StreamObserver<>() {
            @Override
            public void onNext(PersonProto.Person person) {
                log.info("onNext: {}", person);
                result.add(person.toString());
            }

            @Override
            public void onError(Throwable throwable) {
                log.error("onError: {}", throwable.getMessage(), throwable);
            }

            @Override
            public void onCompleted() {
                log.info("onCompleted ,count = {}", result.size());

                responseObserver.onNext(PersonProto.AddPeopleResponse.newBuilder().setCount(result.size()).build());
                responseObserver.onCompleted();
            }
        };
    }

    @Override
    public StreamObserver<PersonProto.AddressBook> syncAddressBook(StreamObserver<PersonProto.AddressBook> responseObserver) {

        ArrayList<String> result = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            responseObserver.onNext(PersonProto.AddressBook.newBuilder()
                    .addPeople(PersonProto.Person.newBuilder()
                            .setName(RandomUtil.randomString(5))
                            .setId(RandomUtil.randomInt())
                            .build())
                    .build());
        }

        return new StreamObserver<>() {
            @Override
            public void onNext(PersonProto.AddressBook addressBook) {
                log.info("onNext: {}", addressBook);
                result.add(addressBook.toString());
                responseObserver.onNext(addressBook);
            }

            @Override
            public void onError(Throwable throwable) {
                log.error("onError: {}", throwable.getMessage(), throwable);
            }

            @Override
            public void onCompleted() {
                log.info("onCompleted");
                log.info("result.size:{}", result.size());
                responseObserver.onCompleted();
            }
        };
    }
}